﻿using CKS.Core.Framework;
using CKS.PLC.Action.System;
using CKS.PLC.Core.Cache;
using CKS.PLC.Core.CronJob;
using CKS.PLC.Core.Reader;
using FreeSql;
using Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Action.Subscription
{
    public class Work02Action: SaveProcessingResults
    {
        SocketReaderClient ReaderClient;
        /// <summary>
        /// 抓取扫码验证
        /// </summary>
        /// <param name="_value"></param>
        public Work02Action(DecodeValue _value) : base(_value)
        {
            ReaderClient = InternalApp.JobProvider.GetService<MonitorClientJob>().Client2;
        }

        public override AfterSaveResult AfterSaved(SaveArg e)
        {
            var barCode = ReaderClient.GetReaderString();//获取扫码内容:托盘码
            var P = Value.Position;
            var act = e.CksAction;
            var replyPos = Value.GetReplyPosition(act.WriteDB, act.ActionId, act.ActionKey);

            //查询动态表记录，填充
            var fsqlTable = e.TableInfo;
            var dict = new Dictionary<string, object>();
            dict["Id"] = e.InsertIdentityId;
            dict["CheckResult"] = "2";
            object obj = null;

            //如果是空内容，说明是扫码NG。添加到异常任务表
            if (barCode.IsNoReade())
            {
                //原流程仅回复NG 不做异常保存
                //回复流转数据空、回复信号 99 
                EventBus.AddLog("机械手抓取扫码NG");
                dict["ContainerNo"] = barCode;
                dict["Info"] = "扫码NG";
                obj = fsqlTable.CreateInstance(dict);
                conn.Update<object>().AsType(fsqlTable.Type)
                    .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();

                var excep = new CksPackagingExceptionTask()
                {
                    NgType = PackageNgType.扫码NG,
                    Location = "抓取位",
                    ContainerNo = barCode,
                    ProductMode = ProductMode
                };
                ServiceCommon.ExceptionTasks.Add(excep);


                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }
            //提取关联点位的流转数据
            string InTaskNo = Value.GetLinkData(1).ToString();

            EventBus.AddLog($"抓取扫码{barCode},PLC数据{InTaskNo} ,");

            //查询任务信息进行验证
            var container = conn.Select<CksContainer>().Where(a => a.ContainerNo == barCode && a.ProductMode == ProductMode).First();
            string TaskNoCheckValue = container == null ? "" : container.TaskNo;
            var task = conn.Select<CksPackagingTask>().Where(a => a.TaskNo == InTaskNo).First();

            dict["TaskNo"] = InTaskNo;
            dict["ContainerNo"] = barCode;
            dict["WaybillNo"] = InTaskNo;
            dict["TaskNoCheckValue"] = TaskNoCheckValue;
            if (!InTaskNo.Equals(TaskNoCheckValue))
            {
                var excep = new CksPackagingExceptionTask()
                {
                    Location = "抓取位",
                    NgType = PackageNgType.校验失败,
                    TaskNo = task.TaskNo,
                    ContainerNo = task.ContainerNo,
                    ProductMode = ProductMode
                };
                ServiceCommon.ExceptionTasks.Add(excep);

                EventBus.AddLog($"抓取校验失败{barCode},PLC{InTaskNo},上位机{TaskNoCheckValue}");
                dict["Info"] = $"抓取校验失败";
                obj = fsqlTable.CreateInstance(dict);
                conn.Update<object>().AsType(fsqlTable.Type)
                    .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();
                if (task != null)
                {
                    task.TaskStatus = TaskStatusType.抓取校验失败;
                    task.Position = "机械手抓取位";
                    conn.Update<CksPackagingTask>().SetSource(task).ExecuteAffrows();
                }

                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }
            
            task.Position = "机械手抓取位";
            task.TaskStatus = TaskStatusType.抓取校验成功;
            task.StepNo = 2;
            conn.Update<CksPackagingTask>().SetSource(task).ExecuteAffrows();

            //保存纸板使用记录
            SaveUsageLog(task);

            EventBus.AddLog($"抓取校验成功");
            dict["Info"] = $"抓取校验成功";
            dict["CheckResult"] = "1";
            obj = fsqlTable.CreateInstance(dict);
            conn.Update<object>().AsType(fsqlTable.Type)
                .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();


            //抓取校验成功
            return base.AfterSaved(e);
        }

        private void SaveUsageLog(CksPackagingTask task)
        {
            var table = conn.Select<CksVirtualTable>().Where(a => a.TableName == "MainWork01").First();
            var columns = conn.Select<CksVirtualColumn>().Where(a => a.TableId == table.Id).OrderBy(a => a.Sequence).ToList();
            var measureTable = ServiceCommon.GetFreesqlTableInfo(table, columns);
            var measureDic = fsql.Select<object>().AsType(measureTable.Type).Where($" TaskNo = '{task.TaskNo}' ")
                .OrderBy("Id desc").First().Adapt<Dictionary<string, object>>();
            var usagelog = new CksCardboardPackagingUsageLog()
            {
                CreatedTime = DateTime.Now,
                TaskNo = task.TaskNo,
                OutputLength = measureDic["OutputLength"].ToDecimal(),
                TypeWidth = measureDic["TypeWidth"].ToInt(),  //UsageWidth TypeWidth

                UsageWidth = measureDic["UsageWidth"].ToDecimal(),
                ProductMode = ProductMode
            };
            usagelog.UsageArea = usagelog.UsageWidth * usagelog.OutputLength;
            usagelog.OutputArea = usagelog.TypeWidth * usagelog.OutputLength;
            usagelog.UtilizationRate = usagelog.OutputArea > 0 ? usagelog.UsageArea / usagelog.OutputArea : 1;
            usagelog.UtilizationRate = usagelog.UtilizationRate.RoundTo4Places(2);
            usagelog.WasteArea = usagelog.OutputArea - usagelog.UsageArea;
            conn.Insert(usagelog).ExecuteAffrows();
        }


    }
}
